JOISC 2023 P1.3 Passport¶
Problem¶
Problem Link¶
https://www.acmicpc.net/problem/27994
https://oj.uz/problem/view/JOI23_passport
Summary¶
\(1, 2, \cdots, N\)번의 \(N\)개의 도시가 있고, 도시 \(i\)에서는 구간 \([L_i, R_i]\) 내의 임의의 도시로 자유롭게 이동할 수 있는 여권을 발급받을 수 있다. \((1 \leq i \leq N)\)
\(Q\)개의 쿼리가 주어질 때, 각 쿼리별로 \(X_k\)번 도시에서 출발하였을 때, 모든 도시를 방문하기 위하여 필요한 여권의 최소 개수를 구하여라. \((1 \leq k \leq Q)\)
Constraints¶
- \(2 \leq N \leq 200,000\)
- \(1 \leq L_i \leq i \leq R_i \leq N\) \((1 \leq i \leq N)\)
- \(1 \leq Q \leq N\)
- \(1 \leq X_k \leq N\) \((1 \leq k \leq Q)\), 모든 \(X_k\)는 서로 다르다.
Solution¶
Subtask 4¶
- \(N \leq 2500\)
현재 갖고 있는 여권들만 사용해서 이동할 수 있는 도시의 범위는 항상 구간이다. \((\because L_i \leq i \leq R_i)\)
따라서, 방문 가능한 도시의 범위가 \([1, N]\)임과, \(L_i=1\)인 여권과 \(R_i=N\)인 여권을 각각 발급받는것은 동치이다.
Observation 1
모든 도시를 방문하기 위하여 발급받아야 하는 여권의 최소 개수는 \(X_k\)번 도시에서 시작해서 \(L_i=1\)인 여권과 \(R_i=N\)인 여권을 각각 발급받기 위하여 발급받아야 하는 여권의 최소 개수와 동치이다.
어떤 도시 \(x\)에서 여권을 발급받아, \([L_x, R_x]\)에 속하는 도시 \(y\)로 이동하여 여권을 발급받는 행동을 \(x\)번 정점에서 \(y\)번 정점으로 이동하는 간선으로 생각하자. 따라서, 문제는 \(X_k\)번 도시에서 시작하여 \(L_i=1\)인 도시 \(L\)과 \(R_i=N\)번 도시 \(R\)로 이동하는 경로를 찾는 것이다. 이 때 경로는 꼭 \(X_k\)에서 시작하여 \(L\)을 방문한 후 \(R\)를 방문할 필요 없이, 중간에 갈라져서 \(L\)로 가는 경로와 \(R\)로 가는 경로를 다르게 선택해도 된다. 물론, 이 때에도 사용한 정점의 총 개수는 중복하지 않고 센다.
위 그림처럼, 최적해는 \(X_k\)에서 시작하여 한 경로를 따라 임의의 정점 \(W\)까지 이동 후, \(W\)에서 갈라져 \(L\)과 \(R\)로 각각 이동하는 형태이다.
Observation 2
\(X_k\)에서 시작하여 정점 \(L\)과 \(R\)로 가는 최단경로의 형태는, 우선 임의의 정점 \(W\)로 이동한 후 갈라져 \(L\)과 \(R\)로 이동하는 것이다. 이 때 \(X_k \rightarrow W\), \(W \rightarrow L\), \(W \rightarrow R\)의 각 경로에는 겹치는 정점이 없다.
이제, 문제를 빠르게 해결하기 위하여 모든 간선의 방향을 뒤집고, 조건을 만족하는 \(L\) 정점들에서 다른 모든 정점들로의 최단경로 \(D_L\), 조건을 만족하는 \(R\) 정점들에서 다른 모든 정점들로의 최단경로 \(D_R\)를 구하자. 이후 각 정점 \(w\)에서 기본 가중치 \(D_L[w]+D_R[w]\)로 시작하여 다른 정점들로 가는 최단경로 \(D\)를 구할 수 있다면, \(D\)가 바로 문제에서 요구하는 답이 됨을 알 수 있다.
모든 간선의 가중치가 1이고, 정점이 \(O(N)\)개, 간선은 \(O(N^2)\)개이니 BFS를 통해 \(O(N^2)\)에 문제를 해결할 수 있다.
CheckPoint
어떤 도시 \(x\)에서 여권을 발급받아, \([L_x, R_x]\)에 속하는 도시 \(y\)로 이동하여 여권을 발급받는 행동을 \(x\)번 정점에서 \(y\)번 정점으로 이동하는 간선으로 생각할 때, Observation 1에 의해 이 그래프에서 \(X_k\)에서 시작하여 \(L_i=1\)인 도시 \(L\)과 \(R_i=N\)번 도시 \(R\)로 이동하는 경로를 찾으면 된다. Observation 2에 의해 이러한 경로는 임의의 정점 \(W\)를 기준으로 \(X_k \rightarrow W\), \(W \rightarrow L\), \(W \rightarrow R\) 3개의 최단 경로의 합을 구하는 문제로 생각할 수 있으니, BFS를 통해 \(O(N^2)\)에 문제를 해결할 수 있다.
Complexity
Subtask 5 (Full)¶
이제 실제로 \(N^2\)개의 간선을 이을 수 없는 상황인데, 간선의 형태가 구간에 있는 모든 정점에서 특정한 점을 연결하는 형태이므로, Segment Tree를 사용하여 최적화할 수 있다. 각 정점을 리프로 하는 Segment Tree를 dummy node로 만들고, Segment Tree의 루트로 방향을 부여하면 특정 구간에서 정점으로 간선을 이을 수 있다. 한 구간에서 정점으로 간선을 연결하는데 \(O(\log N)\)개의 간선만 필요하니, 전체 그래프의 정점은 \(O(N)\), 간선은 \(O(N\log N)\)개이다.
하지만 Segment Tree의 간선들은 가중치가 \(0\)이기 때문에 단순한 BFS를 사용할 수는 없다. Segment Tree에 속하는 간선들은 가중치가 \(0\), 나머지 간선들은 모두 가중치가 1로 전체 그래프의 간선들의 가중치가 \(0\) 혹은 \(1\)이니 01-BFS를 사용하면 \(O(N\log N)\)에 문제를 해결할 수 있다.
CheckPoint
\(O(N^2)\)개의 간선을 Segment Tree를 사용하여 \(O(N\log N)\)개의 간선들로 압축할 수 있다. 이제, 이 그래프에서 가중치가 \(0\) 혹은 \(1\)이니 01-BFS를 사용하면 \(O(N\log N)\)에 문제를 해결할 수 있다.
Complexity
Code¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
|